﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Collections.ObjectModel;

namespace TByte.XnaHelper
{
    public class SpriteSheet
    {
        #region Fields
        Texture2D sheet;
        List<Rectangle> frames;
        List<Vector2> origin;
        #endregion

        #region Methods
        public int Width(int frame)
        {
            if (frame < Count)
            {
                return frames[frame].Width;
            }
            return 0;
        }
        public int Height(int frame)
        {
            if (frame < Count)
            {
                return frames[frame].Height;
            }
            return 0;
        }
        #region DrawMethods
        public void Draw(SpriteBatch spriteBatch)
        {
            Draw(spriteBatch, Vector2.Zero, 0, Color.White, 0, 1, SpriteEffects.None, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position)
        {
            Draw(spriteBatch, position, 0, Color.White, 0, 1, SpriteEffects.None, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int frame)
        {
            Draw(spriteBatch, position, frame, Color.White, 0, 1, SpriteEffects.None, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int frame, Color color)
        {
            Draw(spriteBatch, position, frame, color, 0, 1, SpriteEffects.None, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int frame, Color color, float rotation)
        {
            Draw(spriteBatch, position, frame, color, rotation, 1, SpriteEffects.None, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int frame, Color color, float rotation, float scale)
        {
            Draw(spriteBatch, position, frame, color, rotation, scale, SpriteEffects.None, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int frame, Color color, float rotation, float scale, SpriteEffects spriteEffects)
        {
            Draw(spriteBatch, position, frame, color, rotation, scale, spriteEffects, 0);
        }
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int frame, Color color, float rotation, float scale, SpriteEffects spriteEffects, float depth)
        {
            frame = frame % frames.Count();

            spriteBatch.Draw(sheet, position, frames[frame], color, rotation, origin[frame], scale, spriteEffects, depth);
        }
        #endregion
        public void GenerateCenterOrigin()
        {
            this.origin = new List<Vector2>();

            //Generate center origins
            for (int i = 0; i < frames.Count(); i++)
            {
                origin.Add(new Vector2(frames[i].Width / 2, frames[i].Height / 2));
            }
        }
        public void GenerateZeroOrigin()
        {
            this.origin = new List<Vector2>();

            //Generate center origins
            for (int i = 0; i < frames.Count(); i++)
            {
                origin.Add(Vector2.Zero);
            }
        }
        public void GenerateBottomCenterOrigin()
        {
            this.origin = new List<Vector2>();

            //Generate bottom center origins
            for (int i = 0; i < frames.Count(); i++)
            {
                origin.Add(new Vector2(frames[i].Width / 2, frames[i].Height));
            }
        }
        #endregion

        #region Constructors
        public SpriteSheet(Texture2D sheet, int columns, int rows)
        {
            this.sheet = sheet;
            this.frames = new List<Rectangle>();
            this.origin = new List<Vector2>();

            //Generate the frames
            for (int y = 0; y < rows; y++)
            {
                for (int x = 0; x < columns; x++)
                {
                    frames.Add(new Rectangle(x * sheet.Width / columns, y * sheet.Height / rows, sheet.Width / columns, sheet.Height / rows));
                }
            }

            GenerateZeroOrigin();
        }
        public SpriteSheet(Texture2D sheet, List<Rectangle> frames)
        {
            this.sheet = sheet;
            this.frames = frames;
            this.origin = new List<Vector2>();

            GenerateZeroOrigin();
        }
        public SpriteSheet(Texture2D sheet, List<Rectangle> frames, List<Vector2> origins)
        {
            this.sheet = sheet;
            this.frames = frames;
            this.origin = origins;
        }
        #endregion

        #region Properties
        public int Count { get { return frames.Count; } }
        public ReadOnlyCollection<Vector2> Origins { get { return origin.AsReadOnly(); } }
        #endregion
    }
}
